問題描述
- 現在有兩個字符串已知
- 要求的他們最長的公共子序列長度
例如csdnblog和belong的最長公共子序列是4,由於它們都含有blog這一個子序列
解題思路與算法思想
既然使用動態規劃算法,那麼算法的核心就是將問題分佈
這一點和數學歸納法有點相似
假設含有字符串xc長度爲a
有字符串y長度爲b
現在在比較x的前a1位和y的前b1位置的最長公共子序列
那麼我們需要假設已知之前的所有狀態,如圖:
程序模型的建立
- 先將數據輸入
- 建立轉移方程:
如果當前的兩個字符相同
那麼加一
如果不同
在其他狀態之中選擇一個比較大的
- 之後通過遞歸+記憶的方式計算出匹配的最大字符串
- 最後將匹配的個數輸出
數據結構的選用
選用string去儲存這兩個字符串
程序設計流程
輸入數據
進行計算
輸出結果
程序設計僞碼算法
if((c<0)||(d<0))
{
return 0 ;
}
if(bb[c][d]!=-1)
{
return bb[c][d] ;
}
if(a[c] == b[d] )
{
bb[c][d] = find_num(a,b,c-1,d-1)+1 ;
return bb[c][d] ;
}
else
{
bb[c][d] = max(find_num(a,b,c-1,d),find_num(a,b,c,d-1)) ;
return bb[c][d] ;
}
源程序編碼清單
#include<iostream>
#include<string>
#include<vector>
using namespace std ;
int find_num(string a ,string b ,int c ,int d) ;
vector< vector<int> > bb ;
int main(void)
{
string a ;
string b ;
vector<int>aa ;
cin>>a ;
cin>>b ;
for(int i = 0 ;i<b.size() ;i++)
{
aa.push_back(-1) ;
}
for(int i = 0 ;i<a.size() ;i++)
{
bb.push_back(aa) ;
}
printf("%d",find_num(a,b,a.size()-1,b.size()-1)) ;
}
int find_num(string a ,string b ,int c ,int d)
{
if((c<0)||(d<0))
{
return 0 ;
}
if(bb[c][d]!=-1)
{
return bb[c][d] ;
}
if(a[c] == b[d] )
{
bb[c][d] = find_num(a,b,c-1,d-1)+1 ;
return bb[c][d] ;
}
else
{
bb[c][d] = max(find_num(a,b,c-1,d),find_num(a,b,c,d-1)) ;
return bb[c][d] ;
}
}
程序輸入、輸出
輸入:
csdnblog
belong
輸出:
4
輸入輸出文件,或程序運行結果截圖
時間與空間複雜度分析
時間複雜度是n^2
程序使用說明
總結與完善